defmodule SmartOne.MqttClient do
  use GenServer

  defmodule SampleClient do
    use Hulaaki.Client
    require Logger

    def on_connect(message: message, state: state) do
#      Logger.info "mqtt: connect " <> (IO.inspect message)
      # Kernel.send state.parent, {:connect, message}
    end

    def on_connect_ack(message: message, state: state) do
#      Logger.info "mqtt: connect_ack " <> (IO.inspect message)
      # Kernel.send state.parent, {:connect_ack, message}
    end

    def on_publish(message: message, state: state) do
#      Logger.info "mqtt: publish " <> (IO.inspect message)
      # Kernel.send state.parent, {:publish, message}
    end

    def on_subscribed_publish(message: message, state: state) do
#      Logger.info "mqtt: subscribed_publish " <> (IO.inspect message)
      # Kernel.send state.parent, {:subscribed_publish, message}
    end

    def on_subscribed_publish_ack(message: message, state: state) do
#      Logger.info "mqtt: subscribed_publish " <> (IO.inspect message)
      Kernel.send state.parent, {:subscribed_publish_ack, message}
    end

    def on_publish_receive(message: message, state: state) do
#      Logger.info "mqtt: publish_receive " <> (IO.inspect message)
      # Kernel.send state.parent, {:publish_receive, message}
    end

    def on_publish_release(message: message, state: state) do
#      Logger.info "mqtt: publish_release " <> (IO.inspect message)
      # Kernel.send state.parent, {:publish_release, message}
    end

    def on_publish_complete(message: message, state: state) do
#      Logger.info "mqtt: publish_complete " <> (IO.inspect message)
      # Kernel.send state.parent, {:publish_complete, message}
    end

    def on_publish_ack(message: message, state: state) do
#      Logger.info "mqtt: publish_ack " <> (IO.inspect message)
      # Kernel.send state.parent, {:publish_ack, message}
    end

    def on_subscribe(message: message, state: state) do
#      Logger.info "mqtt: subscribe " <> (IO.inspect message)
      # Kernel.send state.parent, {:subscribe, message}
    end

    def on_subscribe_ack(message: message, state: state) do
#      Logger.info "mqtt: subscribe_ack " <> (IO.inspect message)
      # Kernel.send state.parent, {:subscribe_ack, message}
    end

    def on_unsubscribe(message: message, state: state) do
#      Logger.info "mqtt: unsubscribe " <> (IO.inspect message)
      # Kernel.send state.parent, {:unsubscribe, message}
    end

    def on_unsubscribe_ack(message: message, state: state) do
#      Logger.info "mqtt: unsubscribe_ack " <> (IO.inspect message)
      # Kernel.send state.parent, {:unsubscribe_ack, message}
    end

    def on_ping(message: message, state: state) do
#      Logger.info "mqtt: ping " <> (IO.inspect message)
      # Kernel.send state.parent, {:ping, message}
    end

    def on_pong(message: message, state: state) do
#      Logger.info "mqtt: pong " <> (IO.inspect message)
      # Kernel.send state.parent, {:pong, message}
    end

    def on_disconnect(message: message, state: state) do
#      Logger.info "mqtt: disconnect " <> (IO.inspect message)
      # Kernel.send state.parent, {:disconnect, message}
    end
  end

  def start_link(sup) do
    # {:ok, pid} = SampleClient.start_link(%{parent: self()})
    {:ok, pid} = SampleClient.start_link(%{parent: sup})
    {:ok, _pid} = GenServer.start_link(__MODULE__, pid, name: __MODULE__)
  end

  defp pre_connect(pid) do
    options = [client_id: "some-name", host: "localhost", port: 1883, timeout: 200]
    SampleClient.connect(pid, options)
  end

  defp post_disconnect(pid) do
    SampleClient.disconnect(pid)
    SampleClient.stop(pid)
  end

  def publish_msg(options) do
    GenServer.cast __MODULE__, {:publish, options}
  end

  def handle_cast({:publish, options}, pid) do
    pre_connect pid
    SampleClient.publish(pid, options)
    post_disconnect pid
    {:noreply, pid}
  end

end
